home *** CD-ROM | disk | FTP | other *** search
- #define VERSION "ssed.c 2.2.1 DeSmet 5/20/84\n"
- /*
- * (small/stupid) Stream Editor
- * Accepts a,c,d,i commands only
- * commands are on standard input
- * old file is specified
- * edited result is specified file
- * Line numbers are decimal, . and $
- * Modified for DeSmet by Tom Bonfield
- *
- * Chuck Forsberg
- * Omen Technology Inc
- * Rt 1 Box 120v Portland OR 97231
- * Compuserve: 70715,131
- *
- */
-
- /* system dependent stuff */
- #include <stdio.h>
- #define TRUE 1
- #define FALSE 0
- #define ERROR (-1)
- #define CPMEOF 032
- #define MAXINT 32000
-
- FILE in, out;
-
- #define HUGELINE 1024 /* much easier than crashing if line is too long */
- char *aname; /* name of antecedent file */
- char *oname; /* name of resultant file */
- int linno; /* number of lines that have been output */
- int op1,op2; /* first and (possibly same) last line of cmd */
- char crcseen; /* TRUE if crc given in command line */
- unsigned cmdcrc; /* crc value encountered (decimal) in command line */
- unsigned crc; /* accumulated crc(k) of copied lines from old file */
- char cmd, cmdline[HUGELINE],insline[HUGELINE], *axin;
-
- char Verbose,Unsqueeze, Ignore;
- char cmdeof; /* EOF (cpmeof) seen on command input */
- char ineof; /* EOF (cpmeof) seen on file input */
-
-
- xgetchar()
- {
- return fgetc(stdin);
- }
- int getcr();
- int getcin();
- int (*getthis)(); /* getchar function for current file */
-
- /* Definitions and externals for unsqueezer function */
- #define RECOGNIZE 0xFF76 /* unlikely pattern */
- /* External declarations for USQ feature */
- #define NUMVALS 257 /* 256 data values plus SPEOF*/
- /* Decoding tree */
- struct {
- int children[2]; /* left, right */
- } dnode[NUMVALS - 1];
- int bpos; /* last bit position read */
- int curin; /* last byte value read */
- /* Variables associated with repetition decoding */
- int repct; /*Number of times to return value*/
- int value; /*current byte value or EOF */
- int inch;
-
- getcin()
- {
- return getc(in);
- }
-
- main(argc, argv)
- char **argv;
- {
- char *cp;
-
- getthis=getcin;
-
- Verbose=Ignore=Unsqueeze=FALSE;
- while (--argc && *(cp = *++argv)=='-') {
-
- while( *++cp) {
- switch(tolower(*cp)) {
- case 'i':
- Ignore++; break;
- case 'u':
- Unsqueeze++; break;
- case 'v':
- Verbose++; break;
- default:
- break;
- }
- }
- }
-
- if(argc != 2) {
- fprintf(stderr,VERSION);
- fprintf(stderr,"Usage: ssed [-iuv] infile outfile [<cmdfile]\n");
- fprintf(stderr,"\tEditing commands on stdin\n");
- fprintf(stderr,"\t-i Ignore CRC errors\n");
- fprintf(stderr,"\t-u Unsqueeze infile\n");
- fprintf(stderr,"\t-v Verbose\n");
- exit(1);
- }
-
- if((in=fopen( aname=argv[0], "r")) == NULL) {
- fprintf(stderr, "Can't open %s", aname);
- exit(1);
- }
-
- if((out=fopen( oname=argv[1], "w")) == NULL) {
- fprintf(stderr, "Can't open %s", oname);
- exit(2);
- }
-
- if(Unsqueeze) {
- getthis=getcr; /* switch getchar function */
- init_usq(); /* initialize unpacking */
- }
-
- linno=1; crc=0;
- cmdeof=ineof=FALSE;
-
- while(getcmd()==FALSE) {
-
- if(cmd == 'a') {
- cmd= 'i'; ++op1;
- }
- if(linno>op1) {
- fprintf(stderr,"At line %d: Can't back up to %d\n",
- linno, op1);
- goto fubar;
- }
- while(linno < op1 && ineof==FALSE)
- copyin();
- if(crcseen && cmdcrc != crc) {
- fprintf(stderr,
- "CRC error on Antecedent File %u should be %u\n",
- crc, cmdcrc);
- fprintf(stderr,
- "'%s' is not the correct Antecedent\n", aname);
- if(!Ignore)
- exit(1);
- }
- if(cmd != 'i')
- while(op2-- >= linno && ineof==FALSE)
- chuckline();
- if(cmd=='c' || cmd=='i')
- insert();
- else if(cmd != 'd') {
- fprintf(stderr,"Illegal command %s", cmdline);
- fubar:
- fprintf(stderr,
- "Difference file garbled or not made by dif -e\n");
- exit(1);
- }
- }
- while(ineof == FALSE)
- copyin();
- fprintf(stderr,"Ssed finished\n");
- close(out);
- exit(0);
- }
-
- getcmd()
- {
- crcseen=FALSE;
- if(Verbose) {
- cmdcrc=0;
- fprintf(stderr,"%d:", linno);
- }
- if(cmdeof || lgets(cmdline,xgetchar)==0) {
- if(Verbose)
- fprintf(stderr,"EOF on stdin\n");
- return TRUE;
- }
- axin=cmdline;
- op1=op2=getnum();
- if(*axin==',') {
- ++axin, op2=getnum();
- }
- cmd=tolower(*axin++);
- if(*axin++ == ' ') {
- crcseen=TRUE;
- cmdcrc=atoi(axin);
- }
- if(Verbose)
- fprintf(stderr,"%sop1=%d op2=%d cmd=0%o linno=%d cmdcrc=%u\n",
- cmdline, op1, op2, cmd, linno, cmdcrc);
- return FALSE;
- }
-
- getnum()
- {
- int m;
-
- m=0;
- if(*axin=='.') {
- ++axin; return linno;
- }
- if(*axin=='$') {
- ++axin; return MAXINT;
- }
- while(isdigit(*axin))
- m= (m * 10) + (*axin++ - '0');
- return m;
- }
-
- copyin()
- {
- unsigned crck();
- int len;
-
- if((len=lgets(insline,getthis))==0) {
- ineof=TRUE;
- if(Verbose)
- fprintf(stderr,"EOF on old file\n");
- return;
- }
- if(fputs(insline, out)==ERROR) {
- fprintf(stderr,"Write Error");
- exit(1);
- }
- ++linno;
-
- if(--len>0)
- crc += crck(insline, len, 0);
- }
-
- chuckline()
- {
- if(lgets(insline,getthis)==0) {
- if(Verbose)
- fprintf(stderr,"EOF on old file\n");
- ineof=TRUE;
- return;
- }
- }
-
- insert()
- {
- for(;;) {
- if(lgets(insline,xgetchar)==0) {
- fprintf(stderr,"Unexpected EOF on stdin\n");
- cmdeof=TRUE;
- return;
- }
- if(insline[0]=='.' && insline[1]<=015)
- return;
- if(fputs(insline, out)==ERROR) {
- fprintf(stderr,"Write Error");
- exit(1);
- }
- ++linno;
- }
- }
-
- /* lgets returns length of line read or 0 if eof, gets rid of CR's on input! */
- lgets(s, getfnx)
- char *s;
- int (*getfnx)();
- {
- int c;
- char *p;
- p=s;
- for(;;) {
- switch(c= (*getfnx)()) {
- case 015:
- continue;
- case EOF:
- case CPMEOF:
- return 0;
- case 012:
- *p++ = c;
- *p++ = 0;
- return p-s;
- default:
- *p++ = c; continue;
- }
- }
- }
-
-
-
- /* *** Stuff for first translation module *** */
- #define DLE 0x90
- /* *** Stuff for second translation module *** */
- #define SPEOF 256 /* special endfile token */
- #define LARGE 30000
-
- init_usq()
- {
- int i, c;
- char cc;
-
- char *p;
- int numnodes; /* size of decoding tree */
- char origname[14]; /* Original file name without drive */
-
- /* Initialization */
- init_cr();
- init_huff();
-
- if(getw(in)!=RECOGNIZE) {
- fprintf(stderr,"%s Not Squeezed\n", aname);
- exit(1);
- }
- /* Process rest of header */
- getw(in); /* ignore checksum ... */
-
- /* Get original file name */
- p = origname; /* send it to array */
- do {
- *p = getc(in);
- } while(*p++ != '\0');
-
- numnodes = getw(in);
- if(numnodes < 0 || numnodes >= NUMVALS) {
- fprintf(stderr, "%s has invalid decode tree size\n", aname);
- exit(1);
- }
-
- /* Initialize for possible empty tree (SPEOF only) */
- dnode[0].children[0] = -(SPEOF + 1);
- dnode[0].children[1] = -(SPEOF + 1);
-
- /* Get decoding tree from file */
- for(i = 0; i < numnodes; ++i) {
- dnode[i].children[0] = getw(in);
- dnode[i].children[1] = getw(in);
- }
- }
-
-
- /* initialize decoding functions */
-
- init_cr()
- {
- repct = 0;
- }
-
- init_huff()
- {
- bpos = 99; /* force initial read */
- }
-
- /* Get bytes with decoding - this decodes repetition,
- * calls getuhuff to decode file stream into byte
- * level code with only repetition encoding.
- *
- * The code is simple passing through of bytes except
- * that DLE is encoded as DLE-zero and other values
- * repeated more than twice are encoded as value-DLE-count.
- */
-
- int
- getcr()
- {
- int c;
-
- if(repct > 0) {
- /* Expanding a repeated char */
- --repct;
- return value;
- } else {
- /* Nothing unusual */
- if((c = getuhuff()) != DLE) {
- /* It's not the special delimiter */
- value = c;
- if(value == EOF)
- repct = LARGE;
- return value;
- } else {
- /* Special token */
- if((repct = getuhuff()) == 0)
- /* DLE, zero represents DLE */
- return DLE;
- else {
- /* Begin expanding repetition */
- repct -= 2; /* 2nd time */
- return value;
- }
- }
- }
- }
-
- /* Decode file stream into a byte level code with only
- * repetition encoding remaining.
- */
-
- int
- getuhuff()
- {
- /* Follow bit stream in tree to a leaf*/
- inch = 0; /* Start at root of tree */
- do {
- if(++bpos > 7) {
- if((curin = getc(in)) == ERROR)
- return ERROR;
- bpos = 0;
- /* move a level deeper in tree */
- inch = dnode[inch].children[1 & curin];
- } else
- inch = dnode[inch].children[1 & (curin >>= 1)];
- } while(inch >= 0);
-
- /* Decode fake node index to original data value */
- inch = -(inch + 1);
- /* Decode special endfile token to normal EOF */
- return (inch == SPEOF) ? EOF : inch;
-
- }
-
- /*
- * uses algrithim of CRCK.COM previous to 5.0
- */
- unsigned crck(crbuf, count, oldcrc)
- char *crbuf;
- unsigned oldcrc;
- {
- unsigned n;
- while (--count >= 0) {
- n= (oldcrc << 1);
- n = (n & 0xFF00) | (( n + *crbuf++ ) & 0xFF);
- if(oldcrc & 0x8000)
- n ^= 0xA097;
- oldcrc = n;
- }
- return oldcrc;
- }